from flask import request, jsonify, redirect, url_for, send_from_directory
from functools import wraps
from biz.utils.logger import logger
from biz.config.settings import AuthConfig
import os

def require_token(f):
    """
    装饰器：验证请求头中的x-Authentication-Token
    所有API请求都需要通过此装饰器进行验证
    """
    @wraps(f)
    def decorated(*args, **kwargs):
        # 如果认证被禁用，直接处理请求
        if not AuthConfig.ENABLE_AUTH:
            return f(*args, **kwargs)
            
        # 从请求头中获取token
        token = request.headers.get('x-Authentication-Token')
        
        # 如果没有提供token，返回401未授权错误
        if not token:
            logger.warning("API请求未提供认证令牌")
            return jsonify({"type": "error", "error": "未提供认证令牌"}), 401
        
        # 验证token是否有效
        if token != AuthConfig.API_AUTH_TOKEN:
            logger.warning(f"API请求提供了无效的认证令牌")
            return jsonify({"type": "error", "error": "无效的认证令牌"}), 401
        
        # Token验证通过，继续处理请求
        logger.info("API请求认证成功")
        return f(*args, **kwargs)
    
    return decorated
def apply_auth_middleware(app):
    """
    应用认证中间件到所有API路由和静态页面
    """
    # 如果认证被禁用，直接返回
    if not AuthConfig.ENABLE_AUTH:
        logger.info("API认证已禁用，跳过中间件应用")
        return
        
    # 获取所有已注册的路由规则
    for rule in app.url_map.iter_rules():
        # 只对API路由应用认证
        if rule.rule.startswith('/api/v0/'):
            # 获取原始视图函数
            view_func = app.view_functions[rule.endpoint]
            # 应用认证装饰器
            app.view_functions[rule.endpoint] = require_token(view_func)
    
    # 添加静态页面认证检查
    @app.before_request
    def before_request():
        # 如果是静态文件请求且需要认证
        if not AuthConfig.ALLOW_STATIC_WITHOUT_AUTH and AuthConfig.ENABLE_AUTH:
            # 检查是否是需要保护的页面
            protected_pages = ['/index.html', '/chat.html', '/training.html', '/templates.html']
            
            # 检查是否有认证标记（从前端传来的参数）
            auth_token = request.args.get('auth')
            
            # 根路径重定向到index.html
            if request.path == '/' or request.path == '':
                # 如果没有认证标记，重定向到登录页面
                if not auth_token:
                    return redirect('/login.html?redirect=' + request.url)
                return redirect('/index.html?auth=' + auth_token)
            
            # 检查受保护的页面
            if any(request.path.endswith(page) for page in protected_pages):
                # 如果没有认证标记，重定向到登录页面
                if not auth_token:
                    return redirect('/login.html?redirect=' + request.path)
    
    # 添加登录页面路由
    @app.route('/login.html')
    def login_page():
        return send_from_directory(app.static_folder, 'login.html')
    
    logger.info("已应用API认证中间件到所有API路由")
    logger.info("已添加静态页面认证保护")
    
    # 打印认证配置信息
    logger.info(f"API认证配置: 启用认证={AuthConfig.ENABLE_AUTH}, 静态资源无需认证={AuthConfig.ALLOW_STATIC_WITHOUT_AUTH}")